#coding:utf-8

from models import *
from google.appengine.api import users
import os
import re

from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
from google.appengine.ext.webapp.util import run_wsgi_app
import urllib
from urllib import unquote
from urllib import URLopener
from random import choice
import zlib
import service

user_agents = [
    'Mozilla/5.0 (Windows; U; Windows NT 5.1; it; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11',
    'Opera/9.25 (Windows NT 5.1; U; en)',
    'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)',
    'Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.5 (like Gecko) (Kubuntu)',
    'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.12) Gecko/20070731 Ubuntu/dapper-security Firefox/1.5.0.12',
    'Lynx/2.8.5rel.1 libwww-FM/2.14 SSL-MM/1.4.1 GNUTLS/1.2.9'
]

class MyOpener(URLopener, object):
    version = choice(user_agents)
 

class PublicPage(webapp.RequestHandler):
    def render(self, template_file, template_value):
        path = os.path.join(os.path.dirname(__file__), template_file)
        self.response.out.write(template.render(path, template_value))
    
    def error(self, code):
        if code == 400:
            self.response.set_status(code)
        else:
            self.response.set_status(code)
            
    def is_admin(self):
        return users.is_current_user_admin()
    
    def head(self, *args):
        return self.get(*args) 
    
class Admin(PublicPage):
    def get(self):        
        user = users.get_current_user()
        if user:
            categorys = CoolCategory.all().filter('owner = ', user)
            bookmarks = CoolBookmark.all().filter('owner = ', user)
        else:
            categorys = CoolCategory.all()
            bookmarks = CoolBookmark.all()

        tags = CoolTag.all().order('-bookmarkcount')

        page_size = 10
        max_page = (bookmarks.count() + page_size - 1) / page_size
        page = 1
        page_pattern = re.compile('/page/(\d+)$')
        pattern_list = page_pattern.findall(self.request.path)
        if pattern_list:
            page = int(pattern_list[0])
        if page > max_page:
            page = max_page
        if page <= 0:
            page = 1
        offset = (page - 1) * page_size

        show_prev = False
        show_next = False
        show_prev = not (page == 1)
        show_next = not (page == max_page)
        page_list = []
        cnt = 1
        while cnt < max_page:
            page_list.append(cnt)
            cnt += 1
        
        bookmarks = bookmarks.order('-createtime').fetch(page_size, offset=offset)
        pageurl = '/admin/'
        
        template_value = {"bookmarks": bookmarks,
                        "categorys": categorys,
                        "tags": tags,
                        'pageurl': pageurl,
                        'show_prev': show_prev,
                        'show_next': show_next,
                        'prev': page - 1,
                        'next': page + 1,
                        'page': page,
                        'max_page': max_page,
                        'page_list': page_list,
                        'user': user,
                        'login_url': users.CreateLoginURL(self.request.uri),
                        'logout_url': users.CreateLogoutURL(self.request.uri),
                        }        
        self.render('template/admin.html', template_value)

class AddBookmark(PublicPage):
    def get(self):
        user = users.get_current_user()
        if user:
            categorys = CoolCategory.all().filter('owner = ', user)
        else:
            categorys = CoolCategory.all()

        tags = CoolTag.all().order('-bookmarkcount')
        
        template_value = {"mode": "add",
                        "categorys": categorys,
                        "tags": tags,
                        'user': user,
                        'login_url': users.CreateLoginURL(self.request.uri),
                        'logout_url': users.CreateLogoutURL(self.request.uri),
                        }        
        self.render('template/editbookmark.html', template_value)

    def post(self):
        name = self.request.get('name')
        description = self.request.get('description')
        if len(description) > 500:
            description = description[500]
        url = self.request.get('url')
        owner = users.get_current_user()
        privilege = self.request.get('privilege')

        category_id = int(self.request.get('category'))
        category = CoolCategory.get_by_id(category_id)
        
        tags = self.request.get('tags')
        taglist = service.saveTags(tags)
        
        image = service.getImageByUpload(self.request)
        if not image:
            image = service.getImageByUrl(url)
        
        content = service.getContent(url)        
        
        bookmark = CoolBookmark()
        bookmark.name = name        
        bookmark.description = description
        bookmark.url = url
        bookmark.comments = 0
        bookmark.owner = owner
        bookmark.accesscount = 0
        bookmark.category = category
        bookmark.tags = taglist
        bookmark.privilege = privilege
        bookmark.image = image
        bookmark.zipcontent = content
        bookmark.put()
        
        service.updateCategoryBookmarkCount(category)

        self.redirect('/admin')

class EditBookmark(PublicPage):
    def get(self, id):        
        bookmark = CoolBookmark.get_by_id(int(id))
        
        if not bookmark:
            return self.error(404)
        
        user = users.get_current_user()
        if user:
            categorys = CoolCategory.all().filter('owner = ', user)
        else:
            categorys = CoolCategory.all()

        tags = CoolTag.all().order('-bookmarkcount')
        
        template_value = {"mode": "edit",
                        "bookmark": bookmark,
                        "categorys": categorys,
                        "tags": tags,
                        'user': user,
                        'login_url': users.CreateLoginURL(self.request.uri),
                        'logout_url': users.CreateLogoutURL(self.request.uri),
                        }        
        self.render('template/editbookmark.html', template_value)

    def post(self):
        bookmark_id = int(self.request.get('id'))
        bookmark = CoolBookmark.get_by_id(bookmark_id)
        
        if bookmark:        
            name = self.request.get('name')
            description = self.request.get('description')
            if len(description) > 500:
                description = description[:500]        
            url = self.request.get('url')
            owner = users.get_current_user()
            privilege = self.request.get('privilege')
    
            category_id = int(self.request.get('category'))
            newcategory = CoolCategory.get_by_id(category_id) 
            oldcategory = bookmark.category       
    
            tags = self.request.get('tags')
            taglist = service.saveTags(tags)            

            imageNeedUpdate = False
            image = service.getImageByUpload(self.request)            
            if image:
                imageNeedUpdate = True
            else:
                if url <> str(bookmark.url):
                    image = service.getImageByUrl(url)
                    imageNeedUpdate = True
                else:
                    imageNeedUpdate = False
            
            contentNeedUpdate = False            
            if (url <> str(bookmark.url)) or (not bookmark.zipcontent):
                content = service.getContent(url)
                contentNeedUpdate = True
            
            bookmark.name = name        
            bookmark.description = description
            bookmark.url = url
            bookmark.owner = owner
            bookmark.category = newcategory
            bookmark.tags = taglist
            bookmark.privilege = privilege
            if imageNeedUpdate:
                bookmark.image = image
            if contentNeedUpdate:
                bookmark.zipcontent = content
            bookmark.put()
            
            if newcategory == oldcategory:
                service.updateCategoryBookmarkCount(newcategory)
            else:
                service.updateCategoryBookmarkCount(newcategory)
                service.updateCategoryBookmarkCount(oldcategory)
    
            self.redirect('/admin')

class DeleteBookmark(PublicPage):
    def get(self, id):        
        bookmark = CoolBookmark.get_by_id(int(id))        
        if not bookmark:
            return self.error(404)
        
        category = bookmark.category
        
        bookmark.delete()

        service.updateCategoryBookmarkCount(category)

        self.redirect('/admin')

class AddCategory(PublicPage):
    def get(self):
        user = users.get_current_user()
        if user:
            categorys = CoolCategory.all().filter('owner = ', user)
        else:
            categorys = CoolCategory.all()

        tags = CoolTag.all().order('-bookmarkcount')
        
        template_value = {"mode": "add",
                        "categorys": categorys,
                        "tags": tags,
                        'user': user,
                        'login_url': users.CreateLoginURL(self.request.uri),
                        'logout_url': users.CreateLogoutURL(self.request.uri),
                        }        
        self.render('template/editcategory.html', template_value)

    def post(self):
        name = self.request.get('name')
        owner = users.get_current_user()
        description = self.request.get('description')        

        category = CoolCategory()
        category.name = name
        category.owner = owner
        category.description = description
        category.put()

        self.redirect('/admin')

class EditCategory(PublicPage):
    def get(self, id):        
        category = CoolCategory.get_by_id(int(id))
        
        if not category:
            return self.error(404)
        
        user = users.get_current_user()
        if user:
            categorys = CoolCategory.all().filter('owner = ', user)
        else:
            categorys = CoolCategory.all()

        tags = CoolTag.all().order('-bookmarkcount')
        
        template_value = {"mode": "edit",
                        "category": category,
                        "categorys": categorys,
                        "tags": tags,
                        'user': user,
                        'login_url': users.CreateLoginURL(self.request.uri),
                        'logout_url': users.CreateLogoutURL(self.request.uri),
                        }        
        self.render('template/editcategory.html', template_value)

    def post(self):
        name = self.request.get('name')
        owner = users.get_current_user()
        description = self.request.get('description')        

        category_id = int(self.request.get('id'))
        category = CoolCategory.get_by_id(category_id)
        if not category:
            category = CoolCategory()
        
        category.name = name
        category.owner = owner
        category.description = description
        category.put()

        self.redirect('/admin')

class DeleteCategory(PublicPage):
    def get(self, id):        
        category = CoolCategory.get_by_id(int(id))        
        if not category:
            return self.error(404)

        bookmarks = CoolBookmark.all().filter('category = ', category)
        for bookmark in bookmarks:
            bookmark.category = None
            bookmark.put()

        category.delete()

        self.redirect('/admin')

class Addlog(PublicPage):    
    def post(self):
        content = self.request.get('content')

        log = Devlog()
        log.content = content        
        log.put()

        self.redirect('/admin')

class ShowImage(webapp.RequestHandler):
    def get(self):
        url_pattern = re.compile('/admin/showimage/(\S+)$')
        url_list = url_pattern.findall(self.request.path)
        if url_list:
            url = unquote(url_list[0])
        else:
            return self.error(404)
            
        try:
            urlopen = urllib.URLopener()
            fp = urlopen.open('http://images.websnapr.com/?size=S&key=88275ImzxoSl&url=' + url)
            image = fp.read()
            fp.close()
        except:
            image = None
        
        if image:
            self.response.headers['Content-Type'] = "image"
            self.response.out.write(image)

def main():
  webapp.template.register_template_library('filter')
  application = webapp.WSGIApplication(
                                     [('/admin', Admin),
                                      ('/admin/page/\\d+', Admin),
                                      ('/admin/addlog', Addlog),
                                      ('/admin/bookmark/add', AddBookmark),
                                      ('/admin/bookmark/edit', EditBookmark),
                                      ('/admin/bookmark/edit/(?P<id>[0-9]+)', EditBookmark),
                                      ('/admin/bookmark/delete/(?P<id>[0-9]+)', DeleteBookmark),
                                      ('/admin/category/add', AddCategory),
                                      ('/admin/category/edit', EditCategory),
                                      ('/admin/category/edit/(?P<id>[0-9]+)', EditCategory),
                                      ('/admin/category/delete/(?P<id>[0-9]+)', DeleteCategory),
                                      ('/admin/showimage/\\S+', ShowImage),],
                                     debug=True)
  run_wsgi_app(application)

if __name__ == "__main__":
  main()
